#!/usr/bin/env julia
"""
Validate GSI diagnostic files - Compare Julia vs Fortran output.

This script validates Julia-generated diagnostic files against
Fortran GSI reference files for compatibility verification.
"""

# Add parent directory to load path
push!(LOAD_PATH, joinpath(@__DIR__, "..", "src"))

using Printf
using Dates

# Load diagnostic modules
include("../src/Diagnostics/FortranBinaryIO.jl")
include("../src/Diagnostics/DiagnosticFileFormat.jl")
include("../src/Diagnostics/DiagnosticReaders.jl")

using .FortranBinaryIO
using .DiagnosticFileFormat
using .DiagnosticReaders

"""
    validate_single_file(filename::String)

Validate a single diagnostic file.
"""
function validate_single_file(filename::String)
    println("\n" * "="^80)
    println("VALIDATING: $filename")
    println("="^80)

    is_valid, messages = validate_diagnostic_file(filename)

    for msg in messages
        println(msg)
    end

    println()
    if is_valid
        println("✓ VALIDATION PASSED")
    else
        println("✗ VALIDATION FAILED")
    end
    println("="^80)

    return is_valid
end

"""
    compare_fortran_julia_files(fortran_file::String, julia_file::String)

Compare Fortran GSI diagnostic file with Julia-generated file.
"""
function compare_fortran_julia_files(fortran_file::String, julia_file::String)
    println("\n" * "="^80)
    println("COMPARING FORTRAN GSI vs JULIA GSI FILES")
    println("="^80)
    println("Fortran GSI: $fortran_file")
    println("Julia GSI:   $julia_file")
    println()

    if !isfile(fortran_file)
        println("✗ ERROR: Fortran file not found")
        return false
    end

    if !isfile(julia_file)
        println("✗ ERROR: Julia file not found")
        return false
    end

    # Compare files
    report = compare_diagnostic_files(fortran_file, julia_file, tolerance=1e-4)

    # Assess compatibility
    n_warnings = count(line -> occursin("WARNING", line), report)
    n_errors = count(line -> occursin("ERROR", line), report)

    println("\n" * "="^80)
    println("COMPATIBILITY ASSESSMENT")
    println("="^80)
    println("Warnings: $n_warnings")
    println("Errors:   $n_errors")
    println()

    if n_errors > 0
        println("✗ COMPATIBILITY: POOR - Errors found")
        compatibility = "Poor"
    elseif n_warnings > 3
        println("⚠ COMPATIBILITY: ACCEPTABLE - Multiple warnings")
        compatibility = "Acceptable"
    elseif n_warnings > 0
        println("✓ COMPATIBILITY: GOOD - Minor warnings")
        compatibility = "Good"
    else
        println("✓ COMPATIBILITY: EXCELLENT - No issues")
        compatibility = "Excellent"
    end
    println("="^80)

    return (n_errors == 0, compatibility)
end

"""
    validate_all_diagnostic_files(fortran_dir::String, julia_dir::String)

Validate all diagnostic files in directories.
"""
function validate_all_diagnostic_files(fortran_dir::String, julia_dir::String)
    println("\n" * "="^80)
    println("GSI DIAGNOSTIC FILE VALIDATION SUITE")
    println("="^80)
    println("Fortran GSI directory: $fortran_dir")
    println("Julia GSI directory:   $julia_dir")
    println("Time: $(Dates.format(now(), "yyyy-mm-dd HH:MM:SS"))")
    println("="^80)

    results = Dict{String, Tuple{Bool, String}}()

    # Define file pairs to compare
    file_pairs = [
        ("diag_obs_setup_anl.2018081212", "diag_obs_setup_anl.2018081212"),
        ("diag_obs_setup_ges.ensmean", "diag_obs_setup_ges.ensmean"),
    ]

    for (fortran_file, julia_file) in file_pairs
        fortran_path = joinpath(fortran_dir, fortran_file)
        julia_path = joinpath(julia_dir, julia_file)

        if isfile(fortran_path) && isfile(julia_path)
            passed, compat = compare_fortran_julia_files(fortran_path, julia_path)
            results[julia_file] = (passed, compat)
        elseif isfile(fortran_path)
            println("\n⚠ Julia file not found: $julia_file")
            results[julia_file] = (false, "Not Generated")
        end
    end

    # Check fort.* files
    for var_num in [201, 202, 203, 204]
        fort_file = "fort.$var_num"
        fortran_path = joinpath(fortran_dir, fort_file)
        julia_path = joinpath(julia_dir, fort_file)

        if isfile(fortran_path) && isfile(julia_path)
            println("\n" * "="^80)
            println("COMPARING: $fort_file")
            println("="^80)

            fortran_stats = read_fit_statistics(fortran_path)
            julia_stats = read_fit_statistics(julia_path)

            # Compare statistics
            match = true
            for key in ["count", "bias", "rms", "cpen", "qcpen"]
                f_val = get(fortran_stats, key, 0.0)
                j_val = get(julia_stats, key, 0.0)
                diff = abs(f_val - j_val)

                @printf("  %-10s: Fortran=%.4f  Julia=%.4f  Diff=%.4e\n",
                        key, f_val, j_val, diff)

                if diff > 1e-3 && (f_val != 0.0 || j_val != 0.0)
                    match = false
                end
            end

            compat = match ? "Excellent" : "Acceptable"
            results[fort_file] = (true, compat)
        end
    end

    # Print summary
    print_validation_summary(results)

    return results
end

"""
    print_validation_summary(results::Dict)

Print summary of validation results.
"""
function print_validation_summary(results::Dict)
    println("\n" * "="^80)
    println("VALIDATION SUMMARY")
    println("="^80)

    println(@sprintf("%-40s %-10s %-15s", "File", "Status", "Compatibility"))
    println("-"^80)

    for (file, (passed, compat)) in sort(collect(results))
        status = passed ? "✓ PASS" : "✗ FAIL"
        @printf("%-40s %-10s %-15s\n", file, status, compat)
    end

    println("="^80)

    # Overall assessment
    total = length(results)
    passed = count(p -> p[1], values(results))
    excellent = count(p -> p[2] == "Excellent", values(results))

    println("\nOVERALL ASSESSMENT:")
    println("  Total files: $total")
    println("  Passed: $passed")
    println("  Failed: $(total - passed)")
    println("  Excellent compatibility: $excellent")
    println()

    if passed == total && excellent >= total ÷ 2
        println("✓ OVERALL: EXCELLENT - Ready for production use")
    elseif passed == total
        println("✓ OVERALL: GOOD - Minor differences acceptable")
    elseif passed >= total ÷ 2
        println("⚠ OVERALL: ACCEPTABLE - Some compatibility issues")
    else
        println("✗ OVERALL: POOR - Significant compatibility problems")
    end

    println("="^80)
end

"""
    generate_validation_report(fortran_dir::String, julia_dir::String, output_file::String)

Generate comprehensive validation report.
"""
function generate_validation_report(fortran_dir::String, julia_dir::String,
                                    output_file::String)
    println("\n" * "="^80)
    println("GENERATING VALIDATION REPORT")
    println("="^80)

    # Run validation
    results = validate_all_diagnostic_files(fortran_dir, julia_dir)

    # Write report
    open(output_file, "w") do f
        write(f, "="^80 * "\n")
        write(f, "GSI DIAGNOSTIC FILE VALIDATION REPORT\n")
        write(f, "="^80 * "\n")
        write(f, "Generated: $(Dates.format(now(), "yyyy-mm-dd HH:MM:SS"))\n")
        write(f, "Fortran GSI directory: $fortran_dir\n")
        write(f, "Julia GSI directory:   $julia_dir\n")
        write(f, "="^80 * "\n\n")

        write(f, "VALIDATION RESULTS\n")
        write(f, "-"^80 * "\n")
        write(f, @sprintf("%-40s %-10s %-15s\n", "File", "Status", "Compatibility"))
        write(f, "-"^80 * "\n")

        for (file, (passed, compat)) in sort(collect(results))
            status = passed ? "PASS" : "FAIL"
            write(f, @sprintf("%-40s %-10s %-15s\n", file, status, compat))
        end

        write(f, "="^80 * "\n\n")

        # Summary statistics
        total = length(results)
        passed = count(p -> p[1], values(results))
        excellent = count(p -> p[2] == "Excellent", values(results))
        good = count(p -> p[2] == "Good", values(results))
        acceptable = count(p -> p[2] == "Acceptable", values(results))

        write(f, "SUMMARY STATISTICS\n")
        write(f, "-"^80 * "\n")
        write(f, "Total files validated: $total\n")
        write(f, "Passed: $passed ($(round(100*passed/total, digits=1))%)\n")
        write(f, "Failed: $(total - passed)\n\n")

        write(f, "Compatibility breakdown:\n")
        write(f, "  Excellent: $excellent\n")
        write(f, "  Good: $good\n")
        write(f, "  Acceptable: $acceptable\n")
        write(f, "  Poor: $(total - excellent - good - acceptable)\n")
        write(f, "="^80 * "\n")
    end

    println("✓ Report written to: $output_file")
    println("="^80)

    return results
end

# Main execution
function main()
    # Default directories
    fortran_dir = "/home/linden/comGSI/run/job/basic"
    julia_dir = joinpath(@__DIR__, "..", "results", "diagnostics")

    # Parse command line arguments
    if length(ARGS) >= 1
        fortran_dir = ARGS[1]
    end

    if length(ARGS) >= 2
        julia_dir = ARGS[2]
    end

    # Create Julia output directory if needed
    if !isdir(julia_dir)
        println("Creating Julia diagnostics directory: $julia_dir")
        mkpath(julia_dir)
    end

    # Run validation
    if isdir(fortran_dir)
        report_file = joinpath(@__DIR__, "validation_report.txt")
        generate_validation_report(fortran_dir, julia_dir, report_file)
    else
        println("ERROR: Fortran GSI directory not found: $fortran_dir")
        println("\nUsage: julia validate_diagnostic_files.jl [fortran_dir] [julia_dir]")
        exit(1)
    end
end

# Run if executed as script
if abspath(PROGRAM_FILE) == @__FILE__
    main()
end
